package com.cci.zkweb.core.controller;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.zkoss.util.media.AMedia;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zul.Filedownload;
import org.zkoss.zul.Grid;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listhead;
import org.zkoss.zul.Tree;
import org.zkoss.zul.Treeitem;

import com.cci.zkweb.core.components.BreadCrumb;
import com.cci.zkweb.core.entity.p8.ClassProperty;
import com.cci.zkweb.core.entity.p8.Document;
import com.cci.zkweb.core.entity.p8.Folder;
import com.cci.zkweb.core.entity.p8.P8Object;
import com.cci.zkweb.core.model.FolderContentRenderer;
import com.cci.zkweb.core.model.FolderTreeModel;
import com.cci.zkweb.core.model.FolderTreeRenderer;
import com.cci.zkweb.core.util.SessionUtils;
import com.cci.zkweb.core.util.ZKFUtils;

/**
 * Navigation controller
 * @author durzod
 */
public class FolderNavigationController  
extends SelectorComposer<Component> {
	private static final long serialVersionUID = -2253325663085219992L;
	
	// model
	private FolderTreeModel _model;
	private Treeitem _path;
	
	// Wired components
	@Wire
	Listbox resultGrid;
	Listhead resultGridHead;
	@Wire
	Tree p8FolderTree;
	@Wire
	Grid detailGridCustom;
	@Wire
	Grid detailGridSystem;
	@Wire
	BreadCrumb breadcrumb;
	
	@Override
	public void doAfterCompose(Component comp) 
	throws Exception {
		super.doAfterCompose(comp);

		_model = new FolderTreeModel(getRootNode()); 
		p8FolderTree.setModel(_model);
		p8FolderTree.setItemRenderer(new FolderTreeRenderer());
		resultGrid.setItemRenderer(new FolderContentRenderer());
	}

	/**
	 * Get the root node of the Object Store
	 * @return
	 */
	public Folder getRootNode() {
		return SessionUtils.getSessionItem().getP8Service().getRootFolder();
	}
	
	/**
	 * Create the listbox header dynamically
	 */
	public void setListboxHeader() {
		if(resultGridHead != null) {
			resultGrid.removeChild(resultGridHead);
			resultGridHead.getChildren().clear();
		} else resultGridHead = new Listhead();
		
		resultGridHead.appendChild(ZKFUtils.createListHeader("", "35px", null, null));
		resultGridHead.appendChild(ZKFUtils.createListHeader("Titolo", "450px", null, "auto(name)"));
		resultGridHead.appendChild(ZKFUtils.createListHeader("Dimensione", "100px", "right", null));
		resultGridHead.appendChild(ZKFUtils.createListHeader("Creato da", "100px", null, "auto(author)"));
		resultGridHead.appendChild(ZKFUtils.createListHeader("Classe", "150px", null, "auto(classDoc)"));
		resultGridHead.appendChild(ZKFUtils.createListHeader("Major Version", "100px", null, null));
		resultGridHead.appendChild(ZKFUtils.createListHeader("Minor Version", "100px", null, null));
		resultGridHead.appendChild(ZKFUtils.createListHeader("Modificato da", "100px", null, null));
		
		resultGridHead.setMenupopup("auto");
		resultGridHead.setSizable(true);
		resultGrid.appendChild(resultGridHead);
	}

/////////////////////////////////////////////////
// EVENTS MANAGEMENT SECTION
/////////////////////////////////////////////////
	
	@Listen("onSelect=#p8FolderTree")
	public void selectItemOnTree(Event evt) {
		Folder f = null;
		if(evt.getData() != null) {
			Treeitem it = (Treeitem)evt.getData();
			f = (Folder)it.getValue();
			p8FolderTree.setSelectedItem(it);
		} else {
			f = (Folder) p8FolderTree.getSelectedItem().getValue();
		}
		
		List<P8Object> objectList = new ArrayList<P8Object>();
		if(f.getChildren() == null) {
			List<Folder> folderList = SessionUtils.getSessionItem().getP8Service().getSubFolders(f);
			if(folderList != null) {
				f.setChildren(folderList);
			}
		}
		if(f.getDocList() == null) {
			List<Document> docList = SessionUtils.getSessionItem().getP8Service().getDocumentsInFolder(f);
			if(docList != null) {
				f.setDocList(docList);
			}
		}

		if(f.getChildren() != null) {
			for(Folder _f : f.getChildren()) {
				objectList.add(_f);
			}
		}
		if(f.getDocList() != null) {
			for(Document _d : f.getDocList()) {
				objectList.add(_d);
			}
		}
		_path = p8FolderTree.getSelectedItem();
		breadcrumb.setPath(_path);
		
		p8FolderTree.getSelectedItem().setOpen(true);
		// set the model to the resultGrid to display 
		// folder content
		setListboxHeader();
		resultGrid.setModel(new ListModelList<P8Object>(objectList));
		resultGrid.renderAll();
	}
	
	@Listen("onSelect=#resultGrid")
	public void selectItemOnGrid() {
		// get custom properties
		ListModelList<ClassProperty> modelCustom = new ListModelList<ClassProperty>();
		ListModelList<ClassProperty> modelSystem = new ListModelList<ClassProperty>();
		
		if(resultGrid.getSelectedItem() != null) {
			P8Object obj = resultGrid.getSelectedItem().getValue();
			SessionUtils.getSessionItem().getP8Service().readObjectClassInfo(obj);
			
			modelCustom.addAll(obj.getCustomClassProperties());
			modelSystem.addAll(obj.getSystemClassProperties());
		}
		detailGridCustom.setModel(modelCustom);
		detailGridSystem.setModel(modelSystem);
	}
	
	@Listen("onDoubleClick=#resultGrid")
	public void gridItemDoubleClick() {
		if(resultGrid.getSelectedItem() != null) {
			P8Object item = resultGrid.getSelectedItem().getValue();
			// if is not a folder, start the download of the item
			if(!item.isFolder()) {
				Document doc = (Document)item;
	
				InputStream in = SessionUtils.getSessionItem().getP8Service().getDocumentStream(doc);
				if(in != null) {
					ByteArrayOutputStream out = new ByteArrayOutputStream();
					if(ZKFUtils.PDF_MIME.equals(doc.getMimeType())) {
						String userMail = SessionUtils.getSessionItem().getUserMail();
						out = (ByteArrayOutputStream)ZKFUtils.addWatermarkToPdfStream(in, userMail);
					} 
	
					AMedia amedia = new AMedia(doc.getName(), doc.getExtension(), doc.getMimeType(), out.toByteArray());
					Filedownload.save(amedia);
				}
			// otherwise execute node navigation
			} else {
				// select item on tree
				if(p8FolderTree.getSelectedItem() != null && p8FolderTree.getSelectedItem().getTreechildren() != null) {
					for(Treeitem ti : p8FolderTree.getSelectedItem().getTreechildren().getItems()) {
						if(((Folder)ti.getValue()).equals(item)) {
							p8FolderTree.setSelectedItem(ti);
							break;
						}
					}
				}
				Events.sendEvent(p8FolderTree, new Event(Events.ON_SELECT, p8FolderTree));				
			}
		}
	}
}
